<template>
  <div class="chart">
    <div class="chart-circle"></div>
    <div ref="pieChart" class="chart-box"></div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import { fitChartSize, tooltipOptions } from '../utils/charts'

interface IOptionsItem {
  // 名称
  name?: string
  // 金额
  value?: number
  // 项目状态
  type?: string
}
const props = withDefaults(
  defineProps<{
    data?: IOptionsItem[]
    colors?: string[]
    title?: string
    subtext?: string | number
    // 格式化提示
    format?: string | ((...args: any[]) => string)
  }>(),
  {
    data: () => [],
    title: '',
    subtext: '',
    format: '',
  },
)

const defaultGraphic = [
  {
    type: 'circle',
    kind: 'outsideCircle',
    left: 'center',
    top: 'center',
    shape: {
      r: fitChartSize(105),
    },
    style: {
      fill: 'transparent',
      stroke: 'rgba(108, 128, 151, 1)',
      lineWidth: 1,
    },
  },
  {
    type: 'circle',
    kind: 'innerCircle',
    left: 'center',
    top: 'center',
    shape: {
      r: fitChartSize(58),
    },
    style: {
      fill: 'transparent',
      stroke: 'rgba(108, 128, 151, 1)',
      lineWidth: 1,
    },
  },
  {
    type: 'image',
    style: {
      image: 'down.png',
      width: fitChartSize(7),
      height: fitChartSize(7),
    },
    left: 'center',
    top: '32%',
  },
  {
    type: 'image',
    style: {
      image: 'top.png',
      width: fitChartSize(7),
      height: fitChartSize(7),
    },
    left: 'center',
    bottom: '32%',
  },
  {
    type: 'image',
    style: {
      image: 'right.png',
      width: fitChartSize(7),
      height: fitChartSize(7),
    },
    left: '25%',
    top: 'center',
  },
  {
    type: 'image',
    style: {
      image: 'left.png',
      width: fitChartSize(7),
      height: fitChartSize(7),
    },
    right: '25%',
    top: 'center',
  },
  {
    type: 'image',
    style: {
      image: 'inner-circle.png',
      width: fitChartSize(29),
      height: fitChartSize(29),
    },
    left: 'center',
    top: 'center',
  },
]

const pieChart = ref(null) // 图表容器引用
let myChart = null // 存储图表实例
const emits = defineEmits(['open'])

// 配置选项
const option = ref({
  tooltip: {
    trigger: 'item',
    ...tooltipOptions,
  },
  graphic: defaultGraphic,
  legend: {
    bottom: '0%',
    left: 'center',
    textStyle: {
      fontSize: fitChartSize(12),
      color: 'rgba(208, 222, 238, 1)',
    },
    itemGap: fitChartSize(15), // 增加图例项间距
    itemStyle: {
      borderWidth: 0,
    },
    itemWidth: fitChartSize(8),
    itemHeight: fitChartSize(8),
  },
  color: props.colors, // 全局颜色数组
  series: [
    {
      name: '重要工作完成情况',
      type: 'pie',
      center: ['50%', '50%'], // 调整圆心位置：水平居中，垂直方向45%处
      radius: ['65%', '85%'],
      label: {
        show: false,
        color: 'rgba(208, 222, 238, 1)',
        fontSize: fitChartSize(12),
        formatter: (params) => {
          return `${params.name}: ${params.percent}%`
        },
        percentPrecision: 1,
      },
      labelLine: {
        show: false,
        length: fitChartSize(10),
        length2: fitChartSize(15),
        lineStyle: {
          width: 1,
        },
      },
      data: props.data,
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)',
        },
      },
    },
  ],
})

onMounted(() => {
  initChart()
})

watch(
  () => props.data,
  (newVal) => {
    option.value.series[0].data = newVal
    // 应用配置
    myChart?.setOption(option.value)
  },
  {
    deep: true,
  },
)

function initChart() {
  // 初始化图表
  if (pieChart.value) {
    myChart = echarts.init(pieChart.value)

    // 应用配置
    myChart.setOption(option.value)

    // 窗口变化自适应
    window.addEventListener('resize', handleResize)
    // 绑定点击事件
    myChart.on('click', function (params) {
      if (params.componentType === 'graphic') {
        emits('open')
      }
    })
  }
}

// 处理窗口缩放
const handleResize = () => {
  myChart?.resize()
  updateGraphicElements()
}

const updateGraphicElements = () => {
  // 获取当前配置
  const currentOption = myChart.getOption()

  const currentGraphic = currentOption.graphic[0].elements

  // 更新graphic中所有元素
  if (currentGraphic?.length) {
    currentGraphic.forEach((item) => {
      // 更新圆形半径
      if (item.kind === 'outsideCircle' && item.shape && item.shape.r) {
        item.shape.r = fitChartSize(105)
      }
      if (item.kind === 'innerCircle' && item.shape && item.shape.r) {
        item.shape.r = fitChartSize(58)
      }
    })

    // 应用更新后的配置
    myChart.setOption({
      graphic: currentGraphic,
    })
  }
}

// 组件卸载前清理
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  myChart?.dispose()
})
</script>

<style lang="scss" scoped>
.chart {
  height: vh(378);
  &-box {
    width: vw(220);
    height: vh(350);
  }
}
</style>
